import { DownOutlined, UpOutlined } from "@ant-design/icons"
import type { FlexProps, FormProps } from "antd"
import { Button, Flex, Form, Space } from "antd"
import { DetailedReactHTMLElement, ReactNode, useId, useState } from "react"
import styled from "styled-components"

import { isArray } from "@/utils/is"

import { useSlot } from "../slot"
import { IQueryFormChild } from "./types"

const traverser = (objects: DetailedReactHTMLElement<any, HTMLElement>[], isCollapsed?: boolean): ReactNode[] =>
	!objects
		? []
		: objects.reduce((prev: ReactNode[], object: DetailedReactHTMLElement<any, HTMLElement>) => {
				if (!object?.props?.children) return prev
				const curr = isArray(object?.props?.children)
					? object?.props?.children.map(
							(child: IQueryFormChild) =>
								(!isCollapsed || !child?.isCollapsed) && <Space.Compact key={useId()}>{child}</Space.Compact>
					  )
					: [<Space.Compact key={useId()}>{object?.props?.children}</Space.Compact>]
				if (!curr) return prev
				return [...prev, ...curr]
		  }, [] as ReactNode[])

const StyledCollapseButton = styled(Button)`
	display: block;
	position: absolute;
	bottom: -40px;
	height: 1rem;
	left: calc(50% - 0.5rem);
	height: 32px;
`

type IQueryFormProps = FormProps & {
	children?: ReactNode
	hasCollapse?: boolean
	className?: string
}

const StyledFlex = styled(Flex)<{ isCollapsed: boolean } & FlexProps>`
	max-height: ${props => (props.isCollapsed ? "34px" : "999px")};
	transition: all 0.3s ease-in-out;
	overflow: hidden;
	padding: 0 12px;
`

const QueryForm = (props: IQueryFormProps) => {
	const { children, hasCollapse, className, ...moreProps } = props
	const { formItems, buttons, additional } = useSlot(children)
	const [isCollapsed, setIsCollapsed] = useState(false)

	return (
		<div style={{ position: "relative" }}>
			<StyledFlex isCollapsed={isCollapsed} gap={20} className={className}>
				<Form {...moreProps}>
					<Space size={[16, 16]} wrap>
						{formItems && traverser(formItems, isCollapsed)}
						{buttons && <Space.Compact>{traverser(buttons)}</Space.Compact>}
					</Space>
					{additional && <Space style={{ marginTop: "16px" }}>{additional}</Space>}
				</Form>
			</StyledFlex>
			{hasCollapse && (
				<StyledCollapseButton
					onClick={() => setIsCollapsed(prev => !prev)}
					icon={isCollapsed ? <DownOutlined /> : <UpOutlined />}
				/>
			)}
		</div>
	)
}

export { QueryForm }
